package net.jueb.sniff4j.extr.sendHandler;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.ReferenceCountUtil;
import io.netty.util.internal.logging.InternalLogger;
import io.netty.util.internal.logging.InternalLoggerFactory;
import net.jueb.sniff4j.extr.base.AbstractRuntime;
import net.jueb.sniff4j.extr.filter.DefaultObjectFilter;
import net.jueb.sniff4j.socksCroe.SocksServerUtils;

/**
 * 代理服务器和客户端直接的数据处理handler
 * 将客户端的数据发送到目标主机
 * @author Administrator
 *
 */
public class SendToTargetHandler extends ChannelInboundHandlerAdapter{
	protected static final InternalLogger log = InternalLoggerFactory.getInstance(SendToTargetHandler.class);
	private Channel proxyTargeChannel;
	private AbstractRuntime rt;
	public SendToTargetHandler(Channel proxyTargeChannel,AbstractRuntime rt) {
		this.proxyTargeChannel=proxyTargeChannel;
		this.rt=rt;
	}
	@Override
	public void channelRead(ChannelHandlerContext ctx, Object request)throws Exception 
	{
		if(request==null)
		{
			return;
		}
		//这里是客户端通道的handler,使用客户端请求过滤器
		//使用用户配置的过滤器
		DefaultObjectFilter filter=rt.getCurrentUser(ctx.channel()).getSendToTargetFilter(ctx.channel(),proxyTargeChannel,rt);
		if(filter==null)
		{//使用server的过滤器
			filter=rt.getDefaultToTargetFilter(ctx.channel(),proxyTargeChannel);
		}
		Object obj=request;
		if(filter!=null)
		{
			obj=filter.doFilt(request);
		}
		if(obj==null)
		{//如果重构的消息为null，则表示被丢弃,执行了shell
			return;
		}
		if(proxyTargeChannel.isActive()&&proxyTargeChannel.isWritable()&&proxyTargeChannel.isOpen())
		{
			proxyTargeChannel.writeAndFlush(obj);
			log.debug(">>>>>>>>>>>>>>>>>>客户端发送数据完毕>>>>>>>>>>>>>>>>>>");
			
		}else
		{
			ReferenceCountUtil.release(obj);
			
			log.debug("目标主机关闭连接!");
		}
	}
	 @Override
	 public void channelInactive(ChannelHandlerContext ctx) throws Exception {
		 if(proxyTargeChannel.isActive())
			{
				SocksServerUtils.closeOnFlush(proxyTargeChannel);
			}
	 }
	 @Override
	 public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
		 ctx.close();
	     log.debug("主机:"+ctx.channel().remoteAddress()+":"+cause.getMessage());
	 }
}
